
#include <boost/asio.hpp>
#include <iostream>

using namespace boost::asio::ip;

#define BUFFER_SIZE 1024

// 1.创建Socket
// 2.连接对端IP + 端口
// 3.发送数据
// 4.接受数据

int main() {
  try {
    boost::asio::io_context ioc;

    // 创建服务端终端节点endpoint
    tcp::endpoint ep(address::from_string("192.168.174.1"), 8888);

    // 创建Socket
    tcp::socket socket(ioc);

    boost::system::error_code ec;

    // 连接对端
    socket.connect(ep, ec);

    if (ec) {
      // 连接失败
      std::cout << "error code:" << ec.value()
                << " Message Tip:" << ec.message() << std::endl;

      return ec.value();
    }

    std::cout << "连接服务器IP：" << ep.address() << " 服务器Port:" << ep.port()
              << std::endl;


    for (;;) {
      // 发送数据
      std::cout << "Enter message: ";
      char request[BUFFER_SIZE] = {0};
      std::cin.getline(request, BUFFER_SIZE);
      size_t request_length = strlen(request);
      boost::asio::write(socket, boost::asio::buffer(request, request_length));

      std::cout << "====================" << std::endl;
      // 接受数据
      char receive[BUFFER_SIZE] = {0};

#if 1
      // receive()是一个同步的阻塞读取操作。它尝试从传入的 socket
      // 中读取数据到指定的缓冲区。
      // 它会一直阻塞，直到读取到任意大小的数据，或发生错误。
      size_t receive_length =
          socket.receive(boost::asio::buffer(receive, BUFFER_SIZE));

#else
      // read()是一个同步的阻塞读取操作。它尝试从传入的 socket
      // 中读取数据到指定的缓冲区。
      // 它会一直阻塞，直到读取到大小为BUFFER_SIZE的数据，或发生错误。
      size_t receive_length =
          boost::asio::read(socket, boost::asio::buffer(receive, BUFFER_SIZE));
#endif

      std::cout << "Reply is: ";
      std::cout.write(receive, receive_length);
      std::cout << "\n";
      std::cout << "====================" << std::endl;
    }

  } catch (const std::exception& e) {
    std::cout << "Exception:" << e.what() << std::endl;
  }

  return 0;
}
